const express = require('express')
const sys_menuTables = require('../../db/admin/sys_menu')
const userTable = require('../../db/user/userTable')
const userDetailTable = require('../../db/user/userDetailTable')
const blogTable = require('../../db/blog/blogTable')
const tipOffTable = require('../../db/tip-off/tipOffTable')
const tipOffCommentTable = require('../../db/tip-off/tipOffCommentTable')
const { v4 } = require('uuid')

const sys_adminApp = express()

// 管理员鉴权 非管理员或超管不得访问服务
sys_adminApp.all('/*', async (req, res, next) => {
  let permission = await userTable.findOne({ token: req.headers.authorization })
  if (permission && (permission.isAdmin || permission.superAdmin)) {
    currentUser = permission
    next()
  } else {
    return res.send({
      status: 403,
      message: '无操作权限!'
    })
  }
})

// 获取菜单
sys_adminApp.get('/menus', async (req, res) => {
  const menus = await sys_menuTables.find({}, { _id: false, __v: false })
  if (menus) {
    res.send({
      status: 200,
      message: 'OK',
      data: { menus }
    })
  } else {
    res.send({
      status: 500,
      message: '获取菜单失败！'
    })
  }
})

// 创建菜单接口
sys_adminApp.post('/createMenu', async (req, res) => {
  const { menuData } = req.body

  let pathName = menuData.name ? menuData.name :
    menuData.path.slice(menuData.path.lastIndexOf('/') + 1)

  let menu = {
    id: v4(),
    pid: menuData.pid,
    title: menuData.title,
    path: menuData.path,
    name: pathName,
    component: menuData.component,
    icon: menuData.icon,
    sort: menuData.sort,
    disabled: menuData.disabled
  }

  try {
    await sys_menuTables.create(menu)
    res.send({
      status: 200,
      message: '创建成功！'
    })
  } catch (e) {
    res.send({
      status: 500,
      message: '创建失败！'
    })
  }
})

// 修改菜单接口
sys_adminApp.post('/updateMenu', async (req, res) => {
  const { menuData } = req.body

  let pathName = menuData.name ? menuData.name :
    menuData.path.slice(menuData.path.lastIndexOf('/') + 1)

  let update = {
    pid: menuData.pid,
    title: menuData.title,
    path: menuData.path,
    name: pathName,
    component: menuData.component,
    icon: menuData.icon,
    sort: menuData.sort,
    disabled: menuData.disabled
  }

  try {
    await sys_menuTables.updateOne(
      { id: menuData.id },
      { $set: { ...update } }
    )

    res.send({
      status: 200,
      message: '更新成功！'
    })
  } catch (e) {
    res.send({
      status: 200,
      message: '更新成功！'
    })
  }
})

// 删除菜单接口
sys_adminApp.delete('/menu/:menuId', async (req, res) => {
  const { menuId } = req.params
  try {
    await sys_menuTables.deleteOne({ id: menuId })

    res.send({
      status: 200,
      message: '删除成功！'
    })
  } catch (e) { 
    res.send({
      status: 500,
      message: '删除失败！'
    })
  }
})

// 查询所有未审核的账号
sys_adminApp.get('/audits/user', async (req, res) => { 
  const { limit, skip } = req.query
  const total = (await userTable.find({ approved: false })).length

  const users = await userTable.find(
    { approved: false },
    { __v: false, password: false, token: false },
    { limit: Number(limit), skip: Number(skip), sort: {createTime: -1} }
  )

  if (users.length) {
    res.send({
      status: 200,
      message: '查询成功！',
      data: { users, total }
    })
  } else {
    res.send({
      status: 500,
      message: '查询失败！',
    })
  }
})

// 用户审核通过
sys_adminApp.post('/audits/user', async (req, res) => {
  const { user } = req.body
  const pass = await userTable.updateOne(
    { _id: user._id },
    { $set: {approved: true} }
  )

  if (pass.modifiedCount > 0) {
    res.send({
      status: 200,
      message: '审核通过！'
    })
  } else {
    res.send({
      status: 500,
      message: '审核失败！',
    })
  }
})

// 重审账号 会撤销管理员身份
sys_adminApp.put('/audits/user', async (req, res) => { 
  const { userId } = req.body
  const freeze = await userTable.updateOne(
    { _id: userId },
    { $set: { approved: false, isAdmin: false } }
  )
  if (freeze.modifiedCount < 1) return res.send({ status: 500, message: '重审失败！' })
  res.send({ status: 200, message: '已打回重审！' })
})

// 查询所有未审核的文章
sys_adminApp.get('/audits/blog', async (req, res) => {
  const { limit, skip } = req.query
  const total = (await blogTable.find({ approved: false })).length

  const blogs = await blogTable.find(
    { approved: false },
    {
      _id: false,
      __v: false,
      comment: false,
      likes: false,
      views: false
    },
    { limit: Number(limit), skip: Number(skip), sort: {lastModified: -1} }
  )

  if (blogs.length) {
    const author_ids = []
    blogs.forEach(blog => author_ids.push(blog.author_id))
    const authors = await userTable.find({ _id: { $in: author_ids } })
    const blogData = JSON.parse(JSON.stringify(blogs))
    blogData.forEach((item) => {
      const author = authors.find((user) => String(user._id) === String(item.author_id))
      let userInfo = {
        key: author?.key ? author.key : '',
        userName: author?.userName ? author.userName : '该账号已注销',
        avatar: author?.avatar ? author.avatar : ''
      }
      item.author = userInfo
    })

    res.send({
      status: 200,
      message: '查询成功！',
      data: { blogData, total }
    })
  } else {
    res.send({
      status: 500,
      message: '查询失败！',
    })
  }
})

// 文章审核通过
sys_adminApp.post('/audits/blog', async (req, res) => {
  const { blogId } = req.body
  const pass = await blogTable.updateOne(
    { blogId },
    { $set: { approved: true, lastModified: new Date() } }
  )

  if (pass.modifiedCount > 0) {
    res.send({
      status: 200,
      message: '审核通过！'
    })
  } else {
    res.send({
      status: 500,
      message: '审核失败！',
    })
  }
})

// 重审文章
sys_adminApp.put('/audits/blog', async (req, res) => {
  const { blogId } = req.body
  const pass = await blogTable.updateOne(
    { blogId },
    { $set: { approved: false } }
  )

  if (pass.modifiedCount > 0) {
    res.send({
      status: 200,
      message: '已打回重审！'
    })
  } else {
    res.send({
      status: 500,
      message: '重审失败！',
    })
  }
})

// 查询所有用户信息
sys_adminApp.get('/sys/user', async (req, res) => {
  const { limit, skip, userName, approved, isAdmin } = req.query
  const query = {}
  const filter = {}
  if (limit) filter.limit = Number(limit)
  if (skip) filter.skip = Number(skip)
  if (userName) query.userName = { $regex: userName }
  if (approved) query.approved = approved === 'true'
  if (isAdmin) query.isAdmin = isAdmin === 'true'
  
  const total = (await userTable.find({...query})).length

  const users = await userTable.find(
    {...query},
    { __v: false, password: false, token: false },
    { ...filter, sort: { createTime: -1 } }
  )

  if (users.length) {
    res.send({
      status: 200,
      message: '查询成功！',
      data: { users, total }
    })
  } else {
    res.send({
      status: 500,
      message: '查询失败！',
    })
  }
})

// 查询所有文章
sys_adminApp.get('/sys/blog', async (req, res) => {
  const { limit, skip, title, userName, tag, approved } = req.query
  const query = {}
  const filter = {}
  if (limit) filter.limit = Number(limit)
  if (skip) filter.skip = Number(skip)
  if (title) query.title = { $regex: title }
  if (tag) query.tags = { $regex: tag }
  if (approved) query.approved = approved === 'true'

  if (userName) {
    const users = await userTable.find({ userName: { $regex: userName } })
    const userIds = []
    if (users.length) {
      users.forEach(user => userIds.push(user._id))
    }
    query.author_id = {$in: userIds}
  }

  const total = (await blogTable.find({...query})).length

  const blogs = await blogTable.find(
    {...query},
    {
      _id: false,
      __v: false,
      comment: false,
      likes: false,
      views: false
    },
    { ...filter, sort: { lastModified: -1 } }
  )

  if (blogs.length) {
    const author_ids = []
    blogs.forEach(blog => author_ids.push(blog.author_id))
    const authors = await userTable.find({ _id: { $in: author_ids } })
    const blogData = JSON.parse(JSON.stringify(blogs))
    blogData.forEach((item) => {
      const author = authors.find((user) => String(user._id) === String(item.author_id))
      let userInfo = {
        key: author?.key ? author.key : '',
        userName: author?.userName ? author.userName : '该账号已注销',
        avatar: author?.avatar ? author.avatar : ''
      }
      item.author = userInfo
    })

    res.send({
      status: 200,
      message: '查询成功！',
      data: { blogData, total }
    })
  } else {
    res.send({
      status: 500,
      message: '查询失败！',
    })
  }
})

// 冻结账号
sys_adminApp.post('/sys/freeze', async (req, res) => {
  const { userId } = req.body
  const freeze = await userTable.updateOne(
    { _id: userId },
    { $set: {freezed: true} }
  )
  if (freeze.modifiedCount < 1) return res.send({ status: 500, message: '冻结失败！' })
  res.send({ status: 200, message: '冻结成功！'})
})

// 解冻账号
sys_adminApp.put('/sys/freeze', async (req, res) => {
  const { userId } = req.body
  const freeze = await userTable.updateOne(
    { _id: userId },
    { $set: { freezed: false } }
  )
  if (freeze.modifiedCount < 1) return res.send({ status: 500, message: '解冻失败！' })
  res.send({ status: 200, message: '解冻成功！' })
})

// 设置管理员
sys_adminApp.post('/sys/admin', async (req, res) => { 
  const { userId } = req.body
  const setAdmin = await userTable.updateOne(
    { _id: userId, approved: true },
    { $set: {isAdmin: true } }
  )

  if (setAdmin.modifiedCount < 1) return res.send({ status: 500, message: '设置失败' })
  res.send({ status: 200, message: '设置成功！' })
 
})

// 取消管理员
sys_adminApp.put('/sys/admin', async (req, res) => {
  const { userId } = req.body
  const setAdmin = await userTable.updateOne(
    { _id: userId, isAdmin: true },
    { $set: { isAdmin: false } }
  )

  if (setAdmin.modifiedCount < 1) return res.send({ status: 500, message: '取消失败' })
  res.send({ status: 200, message: '取消成功！' })
})

// 删除账号 保留该账号的文章
sys_adminApp.delete('/sys/user', async (req, res) => {
  const { user } = req.body

  const rmDetails = await userDetailTable.deleteOne({ key: user.key })
  const rmUser = await userTable.deleteOne({ _id: user._id })

  if (rmDetails.deletedCount > 0 && rmUser.deletedCount > 0) {
    res.send({
      status: 200,
      message: '删除成功！'
    })
  } else {
    res.send({
      status: 500,
      message: '删除失败！',
    })
  }
})

// 删除文章
sys_adminApp.delete('/audits/blog', async (req, res) => {
  const { blogId, key } = req.body

  // 如果作者账号还在
  if (key) {
    // 作者文章列表删除对应的文章 ID
    await userDetailTable.updateOne(
      { key },
      { $pull: { articles: blogId } }
    )
  }

  // 删除所有人对该文章的点赞数据
  await userDetailTable.updateMany(
    { likes: blogId },
    { $pull: { likes: blogId } }
  )

  // 删除所有人对该文章的评论数据
  await userDetailTable.updateMany(
    { comments: { $elemMatch: { blogId } } },
    { $pull: { comments: { blogId } } }
  )

  // 删除所有关于该文章的举报数据
  const rmTipOff = await tipOffTable.deleteMany({blogId})

  // 删除文章
  const rmUser = await blogTable.deleteOne({ blogId })

  if (rmUser.deletedCount > 0 || rmTipOff.deletedCount > 0) {
    res.send({
      status: 200,
      message: '删除成功！'
    })
  } else {
    res.send({
      status: 500,
      message: '删除失败！',
    })
  }
})

// 查询文章举报信息
sys_adminApp.get('/tip-off/blog', async (req, res) => { 
  const { limit, skip } = req.query

  const total = (await tipOffTable.find({})).length
  if (!total) return res.send({ status: 404, message: '暂无数据！' })

  const tips = await tipOffTable.find(
    {},
    { _id: false, __v: false },
    {limit: Number(limit), skip: Number(skip)}
  )
  
  // 更新作者信息
  const authors = []
  tips.forEach(tip => authors.push(tip.author_id))
  const authorInfos = await userTable.find({ _id: { $in: authors } })
  const tipData = JSON.parse(JSON.stringify(tips))
  tipData.forEach(item => {
    let author = authorInfos.find(user => String(item.author_id) === String(user._id))
    item.author = {
      userName: author?.userName ? author.userName : '该账号已注销',
      avatar: author?.avatar ? author.avatar : ''
    }
  })
  res.send({
    status: 200,
    message: '查询成功！',
    data: {total,tipData}
  })
})

// 忽略文章举报
sys_adminApp.delete('/tip-off/blog', async (req, res) => {
  const { tipOffId } = req.body
  const rmTip = await tipOffTable.deleteOne({ tipOffId })
  if (rmTip.deletedCount < 1) return res.send({status: 500, message: '删除失败！'})
  res.send({status: 200, message: '删除成功！'})
})

// 查询评论举报信息
sys_adminApp.get('/tip-off/comment', async (req, res) => {
  const { limit, skip } = req.query

  const total = (await tipOffCommentTable.find({})).length
  if (!total) return res.send({ status: 404, message: '暂无数据！' })

  const tips = await tipOffCommentTable.find(
    {},
    { _id: false, __v: false },
    { limit: Number(limit), skip: Number(skip) }
  )

  // 更新评论者的信息
  const authors = []
  tips.forEach(tip => authors.push(tip.commentator_id))
  const authorInfos = await userTable.find({ _id: { $in: authors } })
  const tipData = JSON.parse(JSON.stringify(tips))
  tipData.forEach(item => {
    let author = authorInfos.find(user => String(item.commentator_id) === String(user._id))
    item.author = {
      userName: author?.userName ? author.userName : '该账号已注销',
      avatar: author?.avatar ? author.avatar : ''
    }
  })
  res.send({
    status: 200,
    message: '查询成功！',
    data: { total, tipData }
  })
})

// 忽略评论举报
sys_adminApp.delete('/tip-off/comment', async (req, res) => {
  const { tipOffId } = req.body
  const rmTip = await tipOffCommentTable.deleteOne({ tipOffId })
  if (rmTip.deletedCount < 1) return res.send({ status: 500, message: '删除失败！' })
  res.send({ status: 200, message: '删除成功！' })
})

// 获取访客信息
sys_adminApp.get('/visitorIps', async (req, res) => {
  const { limit, skip } = req.query
  const total = (await visitorIpTable.find({})).length
  if (!total) return res.send({ status: 404, message: '暂无数据！' })
  const ips = await visitorIpTable.find(
    {},
    { _id: false, __v: false },
    { limit: Number(limit), skip: Number(skip), sort: { visitTime: -1 } }
  )
  res.send({
    status: 200,
    message: '查询成功！',
    data: { total, ips }
  })
})

module.exports = sys_adminApp